/*
 * L9Http.h
 *
 *  Created on: 2011-11-23
 *      Author: baixp
 */

#ifndef L9HTTP_H_
#define L9HTTP_H_
#include <FBase.h>
#include <FNet.h>
#include "L9Util.h"
#include "L9Str.h"
#include "L9Log.h"
#include "L9InputStream.h"
using namespace Osp::Base;
using namespace Osp::Base::Collection;
using namespace Osp::Base::Runtime;
using namespace Osp::Net::Http;
namespace lib9bada {
class L9Http: public Thread, public IHttpTransactionEventListener {
private:
	bool bInProgress;// = false;
	bool bCanceled;
	bool bError;
	pByte pResponse;// = null;
	bool bFirstHttpConnection;// = true;
	int HttpConnectionTimeOut;// = 45;

	HttpSession* pHttpSession;
	HttpTransaction* pHttpTransaction;

	pByte postData;//;

	String sHost;// = "";
	/*static const*/
	String K_Http;// = "http://";
	String sQuery;// = "";

	String getHttpUrl();
	String getHttpHost();
	void defaultInit();


	result TestHttpGet() {
		String* pProxyAddr = null;

		String hostAddr = getHttpHost();// L"http://localhost";
		String uri = getHttpUrl();//L"http://localhost/lib9/testHttp.aspx";

		//		HttpSession* pHttpSession = null;
		//		HttpTransaction* pHttpTransaction = null;
		HttpRequest* pHttpRequest = null;
		HttpHeader* pHttpHeader = null;
		// Create HTTP Session
		result r = E_SUCCESS;
		pHttpSession = new HttpSession();
		r = pHttpSession->Construct(NET_HTTP_SESSION_MODE_NORMAL, pProxyAddr,
				hostAddr, null);
		if (IsFailed(r))
			goto CATCH;

		// Open a new Http Transaction within the HttpSession
		pHttpTransaction = pHttpSession->OpenTransactionN();
		if (null == pHttpTransaction) {
			r = GetLastResult();
			goto CATCH;
		}

		// Add Listener
		// OnTransactionCompleted() will be called when response is arrived
		r = pHttpTransaction->AddHttpTransactionListener(*this);
		if (IsFailed(r))
			goto CATCH;

		// Get Http Request
		pHttpRequest = pHttpTransaction->GetRequest();
		if (pHttpRequest == null) {
			r = GetLastResult();
			goto CATCH;
		}

		// Set HTTP Method
		r = pHttpRequest->SetMethod(NET_HTTP_METHOD_POST);
		if (IsFailed(r))
			goto CATCH;

		// Set Uri
		r = pHttpRequest->SetUri(uri);
		if (IsFailed(r))
			goto CATCH;

		// Fill HTTP Header
		pHttpHeader = pHttpRequest->GetHeader();
		//Add a chunked field to header.
		pHttpHeader->AddField(L"Content-Type", L"application/octet-stream");
		//		pHttpHeader->AddField("Accept", "*/*");//这句话要出错

		//Set a Body to Request.

		if (postData.pChar != null && postData.size > 0) {
			String headSize = L"";
			headSize.Append(postData.size);
			pHttpHeader->AddField(L"Content-Length", headSize);
			//Enable OnTransactionReadyToWrite()
			pHttpTransaction->EnableTransactionReadyToWrite();

			ByteBuffer buf;
			buf.Construct(postData.size);
			buf.SetArray(postData.pChar, 0, postData.size);
			buf.Flip();

			r = pHttpRequest->WriteBody(buf);
			if (IsFailed(r))
				goto CATCH;
		}

		// Submit a request with chunked mode
		r = pHttpTransaction->Submit();
		if (IsFailed(r))
			goto CATCH;

		return r;

		CATCH: bError = true;
		closeHttp();
		AppLog("TestHttpGet() failed. (%s)", GetErrorMessage(r));
		return r;
	}
public:
	L9Http();
	virtual ~L9Http();
	/**
	 * 返回从服务器获取的数据
	 * @return pByte
	 */
	pByte getData();

	/**
	 * 返回是否正在http连接中
	 * @return bool
	 */
	bool isInProcess();
	/**
	 * 返回http连接过程是否有错误发生
	 * @return bool
	 */
	bool isError();
	/**
	 * 取消http连接
	 */
	void cancelHttp();
	/**
	 * 关闭http连接并释放有关资源
	 */
	void closeHttp();

	/**
	 * 进行http连接，使用post方式来传递数据,head为向服务器传递的数据
	 * @param url String
	 * @param head char[]
	 */
	void openHttp(String url, byte* pHead, int off, int size);
	void openHttp(String url);

	void OnTransactionReadyToRead(HttpSession& httpSession,
			HttpTransaction& httpTransaction, int availableBodyLen) {
		AppLog("OnTransactionReadyToRead\n");

		HttpTransaction* pTransaction =
				const_cast<HttpTransaction*> (&(httpTransaction));
		HttpResponse* pHttpResponse = pTransaction->GetResponse();
		ByteBuffer* pBody = null;
		int status = pHttpResponse->GetHttpStatusCode();
		if (status != HTTP_STATUS_OK) {
			closeHttp();
			bError = true;
		} else {
			if (bCanceled) {//用户取消了
				closeHttp();
			}
			pBody = pHttpResponse->ReadBodyN();

			if (pResponse.pChar != null) {
				delete[] pResponse.pChar;
			}
			pResponse.size = availableBodyLen;
			pResponse.pChar = new byte[availableBodyLen];
			pBody->GetArray(pResponse.pChar, 0, availableBodyLen);

			//			L9InputStream in(pResponse.pChar, 0, pResponse.size);
			//			String name = in.readString();
			//			int score = in.readInt();
			//			String desc = in.readString();

			delete pBody;

			bInProgress = false;
		}
		//		responseBin = pResponse->ReadBodyN();

		//		int status = pResponse->GetHttpStatusCode();
		//		if (status != NET_HTTP_STATUS_OK) { //注册或者找回信息判断连接网络 连接超时
		//			closeHttp();
		//			bError = true;
		//			//			throw new Exception("status=" + status);
		//		} else {
		////			//处理移动资费页面
		////			HttpHeader* pResponseHeader = pResponse->GetHeader();
		////			IEnumerator* pList = pResponseHeader->GetFieldValuesN(
		////					"Content-Type");
		////			String* pStr = (String*) (pList->GetCurrent());
		////			String s = *pStr;
		////			if (s != null) {
		////				s.ToUpperCase();
		////				if (!s.StartsWith(Content_Type, 0)) { //如果返回的结果不是设置的类型则重新连接
		////					openHttp(getHttpUrl(), postData.pChar, postData.size);
		////					return null;
		////				}
		////			}
		//			responseBin = pResponse->ReadBodyN();
		//			int x=5;
		//		}
	}

	void OnTransactionAborted(HttpSession& httpSession,
			HttpTransaction& httpTransaction, result r) {
		AppLog("OnTransactionAborted\n");
		bError = true;
		closeHttp();
	}

	void OnTransactionReadyToWrite(HttpSession& httpSession,
			HttpTransaction& httpTransaction, int recommendedChunkSize) {
		AppLog("OnTransactionReadyToWrite\n");
	}

	void OnTransactionHeaderCompleted(HttpSession& httpSession,
			HttpTransaction& httpTransaction, int headerLen, bool bAuthRequired) {
		AppLog("OnTransactionHeaderCompleted\n");
	}

	void OnTransactionCompleted(HttpSession& httpSession,
			HttpTransaction& httpTransaction) {
		AppLog("OnTransactionCompleted\n");
		closeHttp();
	}

	void OnTransactionCertVerificationRequiredN(HttpSession& httpSession,
			HttpTransaction& httpTransaction, String* pCert) {
		AppLog("OnTransactionCertVerificationRequiredN\n");
	}

	void OnUserEventReceivedN(RequestId requestId,
			Osp::Base::Collection::IList *pArgs);

	//	result Construct(void);
	virtual bool OnStart(void);
	virtual void OnStop(void);

};
};

#endif /* L9HTTP_H_ */
